Streamlines can be understood as the curved path of an imaginary particle
released at a certain point in the grid, and `moved' by a certain vector field.
More formally: it is the integral of the vector field $\mathbf{v}$ over some
interval $T$ and starting from the location $p_0$ \cite{scivisbookch06}:
\begin{equation}
  S = \left\{p(\tau), \tau \in [0,T]\right\},p(\tau) = \int_{t =
  0}^\tau \mathbf{v}(p)dt,
\end{equation}
where $p(0)$ is $p_0$. Since streamlines are defined for time-independent
vector fields, the \textit{integration time} $t$ should not be confused with
the \textit{physical time} of a time-dependent dataset. Instead, the physical
time is constant when determining $S$.

\paragraph{Implementation}
The class \texttt{Streamlines} offers functionality to add \textit{seedpoints}
interactively. After pressing a ``Set seed'' button, a mouse click in the
visualization will set a seedpoint in the corresponding location. At each draw
step, a streamline is traced from each of these seedpoints. The procedure is
the following:
\begin{enumerate}
  \item Obtain the value of the vector field $\mathbf{v}(p_c)$ of the current
    position $p_c$ (the first position is the seedpoint).
  \item Calculate the unit vector $\mathbf{\hat{v}}(p_c) = \mathbf{v}(p_c) /
    \lVert\mathbf{v}(p_c)\rVert$.
  \item Obtain the new position $p_n = p_c + \mathbf{\hat{v}}(p_c) \Delta t$.
  \item Draw a line connecting $p_c$ and $p_n$.
  \item $p_c \leftarrow p_n$
  \item Repeat 1 - 5 until the number of lines drawn exceeds some number.
\end{enumerate}
Here, we normalize the vector length to ensure that every drawn line has the
same length. In \cite{scivisbookch06} a different procedure is used: Instead
of normalizing the vector field value, $\Delta t$ is locally adapted to ensure
that each integration step has the same length.  Both solutions prevent that a
streamline segment skips a sample point when the vector field value at $p_c$ is
high. Like all \texttt{Visualizer}s, \texttt{Streamlines} is linked to a scalar
dataset as well. The values of that scalar dataset at $p_c$ at the segment
endpoints can be used to determine the color of the drawn segments.  When a
streamline crosses the border of the visualization, its out-of-bounds
coordinates are circularly shifted. This way, the streamline continues at the
other side of the visualization. The values of $\Delta t$ and the maximum
number of line segments drawn can be interactively adjusted by the user. Some
implementations of streamlines also allow the maximum length of the streamline
to be set. That would not make sense in our case, since each of the segments
has a constant length. The user also has the option to immediately add a large
number of seedpoints uniformly distributed on a grid. Figure
\ref{fig:streamlines} shows the streamlines seeded from such a grid.

\begin{figure}[ht]
  \begin{center}
    \begin{subfigure}[b]{0.49\linewidth}
      \centering
      \includegraphics[width=\textwidth]{./images/Streamlines_colorV.png}
      \caption{}
    \end{subfigure}
    \begin{subfigure}[b]{0.49\linewidth}
      \centering
      \includegraphics[trim=0mm 2mm 0mm 3.5mm,clip,width=\textwidth]{./images/streamline_gradRho_smoke.png}
      \caption{}
      \label{sub:streamgradient}
    \end{subfigure}
  \end{center}
  \caption{Streamlines seeded from a grid of seedpoints. In (a), the
    streamlines trace the fluid flow vector field and are colored using the
    velocity  magnitude scalar field. In (b), they trace the gradient of the fluid
    density and are colored using a constant color map. \texttt{Smoke}
    visualizes the fluid density on the background.}
  \label{fig:streamlines}
\end{figure}
